package com.twb.core.security.jwt;
import java.util.Date;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.lang3.StringUtils;

import com.alibaba.fastjson.JSON;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

/** 
 * @ClassName JwtUtil 
 * @Description jwt安全令牌工具类
 * @author DSY
 * @date 2017年3月24日 上午11:13:10 
 */ 
public class JwtUtil {
	
	/**
	 * @Title generalKey
	 * @Class JwtUtil.java
	 * @Package com.tw.base.jwt
	 * @Description 由字符串生成加密key
	 * @param appToken  app前端系统接入私钥
	 * @param appSecret  app前端系统接入密钥
	 * @return
	 * @author DSY
	 * @date 2017年3月24日 上午11:08:03
	 */
	public static SecretKey generalKey(String appToken,String appSecret){
		if(StringUtils.isEmpty(appToken)) {
			appToken="TWB-SYS";
		}
		if(StringUtils.isEmpty(appSecret)) {
			appToken="7786df7fc3a34e26a61c034d5ec8245d";
		}
		String stringKey = appToken+appSecret;
		byte[] encodedKey = stringKey.getBytes();
		
	    SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
	    return key;
	}

	/**
	 * @Title createJWT
	 * @Class JwtUtil.java
	 * @Package com.tw.base.jwt
	 * @Description 创建jwt
	 * @param id 签发者id即前端系统接入id
	 * @param subject 用户个人信息
	 * @param ttlMillis 有效时间
	 * @param appToken app前端系统接入私钥
	 * @param appSecret app前端系统接入密钥
	 * @return
	 * @throws Exception
	 * @author DSY
	 * @date 2017年3月24日 上午11:08:31
	 */
	public static String createJWT(String id, String subject, long ttlMillis,String appToken,String appSecret) throws Exception {
		SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
		long nowMillis = System.currentTimeMillis();
		Date now = new Date(nowMillis);
		SecretKey key = generalKey(appToken,appSecret);//根据私有密钥生成加密密钥
		JwtBuilder builder = Jwts.builder()//jwt的payload荷载信息，等同于claims。payload、claims二选一即可
			.setId(id)//貌似是签发者ID
			.setIssuer(id)//token签发者
			.setIssuedAt(now)//token签发时间
			.setSubject(subject)//该JWT所面向的用户
		    .signWith(signatureAlgorithm, key);//加密方式，私密密钥
		if (ttlMillis >= 0) {
		    long expMillis = nowMillis + ttlMillis;
		    Date exp = new Date(expMillis);
		    builder.setExpiration(exp);//过期时间
		}
		return builder.compact();
	}
	
	/**
	 * @Title parseJWT
	 * @Class JwtUtil.java
	 * @Package com.tw.base.jwt
	 * @Description 解密jwtToken
	 * @param jwtToken 安全令牌
	 * @param appToken app前端系统接入私钥
	 * @param appSecret app前端系统接入密钥
	 * @return
	 * @author DSY
	 * @date 2017年3月24日 上午11:10:31
	 */
	public static Claims parseJWT(String jwtToken,String appToken,String appSecret){
		SecretKey key = generalKey(appToken,appSecret);
		Claims claims = Jwts.parser()         
		   .setSigningKey(key)
		   .parseClaimsJws(jwtToken).getBody();
		return claims;
	}
	
	/**
	 * @Title isValid
	 * @Class JwtUtil.java
	 * @Package com.tw.base.jwt
	 * @Description 验证token的有效性,如果验证失败会抛出异常
	 * @param jwtToken 安全令牌
	 * @param appToken app前端系统接入私钥
	 * @param appSecret app前端系统接入密钥
	 * @return
	 * @author DSY
	 * @date 2017年3月24日 上午11:11:01
	 */
	public static boolean isValid(String jwtToken,String appToken,String appSecret) {
        try {
        	SecretKey key = generalKey(appToken,appSecret);
            Jwts.parser().setSigningKey(key).parseClaimsJws(jwtToken.trim());
            return true;
        } catch (Exception e) {
            return false;
        }
    }
	/**
	 * 生成subject信息
	 * @param id 用户ID，视具体情况可增加
	 * @return
	 */
	public static String generalSubject(Subject subject){
		return JSON.toJSONString(subject);
	}
}